#ifndef _CHARACTER_H_
#define _CHARACTER_H_

#include "Common.h"
#include "String.h"
#include "SharedPtr.h"
#include "Resource.h"
#include "Effects.h"
#include "Items.h"
#include "Vector3.h"
#include "XMLData.h"

class CharPtr;
class ArmyPtr;
class EfffectPtr;
class MissionPtr;
class CreatureAIScript;


#define CHAR_FIELD_GUID			OBJECT_FIELD_GUID 
#define CHAR_FIELD_SERIAL		OBJECT_FIELD_SERIAL
#define CHAR_FIELD_SID			OBJECT_FIELD_SERVER	// '服务器ID',
#define CHAR_FIELD_NAME			OBJECT_STRING		// '物品名称',
#define CHAR_FIELD_NAME2		OBJECT_STRING 		// '角色更改后名称',
#define CHAR_FIELD_OWNERID		OBJECT_END + 0x0004   	// '隶属角色id',
#define CHAR_FIELD_WORKERS		OBJECT_END + 0x0005   	// '使用职业',
#define CHAR_FIELD_DESC			OBJECT_STRING  		// '描述',
#define CHAR_FIELD_CREATE_TIME		OBJECT_END + 0x0023	// '创建时间',
#define CHAR_FIELD_NUM			OBJECT_END + 0x0024



enum CharacterStatus
{
	CharacterStatusNone			=0,	//无效的武将状态
	CharacterStatusFree			=0x01,	//武将在野
	CharacterStatusServe			=0x02,	//武将任仕
	CharacterStatusMission			=0x04,	//武将执行任务
	CharacterStatusWar			=0x08,	//武将战斗中
	CharacterStatusDamaged			=0x10,	//武将受伤
	CharacterStatusDeath			=0x20,	//武将死亡
	CharacterStatusDeleted			=255	//武将已经删除
};


//武将公共属性
typedef struct charater_common_property
{

	CharacterStatus		status;
	uint32		clientID;		//网络连接 SocketID

	Vector3		position;		//武将位置
	uint8		dir;			//武将方向

	void	*	ext;		//数据扩展
	
	ResourceProxy	uplink;		//战场记录战场的ID

	void initialize(void)
	{

		uplink.setNull();
		clientID = 0;
		position = Vector3::ZERO;
		dir = 4;
		ext = NULL;
		status = CharacterStatusNone;

	}

	charater_common_property()
	{
		initialize();
	}

}character_common_property_t;

class Character :public Resource
{
public:

	enum CharacterEquipLayer
	{
		CharEquipLayerNone			= 0,	//无装备层
		CharEquipLayerHand			= 1,	//单手武器
		CharEquipLayerShield			= 2,	//盾牌双手武器
		CharEquipLayerHead			= 3,	//头部
		CharEquipLayerChest			= 4,	//胸部
		CharEquipLayerUnused			= 5,	//颈部（未用)
		CharEquipLayerLegs			= 6,	//腿部
		CharEquipLayerShoes			= 7,	//脚部
		CharEquipLayerRing			= 8,	//饰品
		CharEquipLayerBack			= 9,	//背部(披风 翅膀)
		CharEquipLayerMount			= 10, 	//坐骑
		CharEquipLayerSuit			= 11,	//套装

		CharEquipLayerSpell1			= 15,	//技能1
		CharEquipLayerSpell2			= 16,   //技能2
		CharEquipLayerSpell3			= 17,	//技能3
		CharEquipLayerSpell4			= 18,	//技能4
		CharEquipLayerSpell5			= 19,	//技能5
		CharEquipLayerSpell6			= 20,	//技能6
		CharEquipLayerSpell7			= 21,	//技能7
		CharEquipLayerSpell8			= 22,	//技能8
		CharEquipLayerSpell9			= 23,	//技能9
		CharEquipLayerSpell10			= 24,	//技能10
		CharEquipLayerArmy1			= 30,	//兵符1
		CharEquipLayerArmy2			= 31,	//兵符2
		CharEquipLayerArmy3			= 32,	//兵符3
		CharEquipLayerArmy4			= 33,	//兵符4
		CharEquipLayerArmy5			= 34,	//兵符5
		CharEquipLayerLineup1			= 40,	//阵形1
		CharEquipLayerLineup2			= 41,	//阵形2
		CharEquipLayerLineup3			= 42,	//阵形3
		CharEquipLayerLineup4			= 43,	//阵形4
		CharEquipLayerLineup5			= 44,	//阵形5
		

		CharEquipLayerBackpack			= 50,	//玩家背包
		CharEquipLayerBackpack2			= 51,	//玩家临时背包
		CharEquipLayerMoney			= 52,	//玩家钱币层
		CharEquipLayerBankMoney			= 53,	//玩家银行钱币层
	
	

		CharEquipLayerNPCRestock		= 60,	//NPC收购容器层
		CharEquipLayerNPCSell			= 61,	//NPC贩卖容器层
		
		CharEquipLayerView			= 62,	//玩家可视装备层
		CharEquipLayerBank			= 62,	//玩家仓库
		CharEquipLayerTrade			= 63,	//玩家交易包
		
		CharEquipLayerDefenseItem		= 65,	//角色防御营寨
		CharEquipLayerTactic			= 66,	//角色的策略	

		CharEquipBattleItem1			= 80,	//战斗物品1
		CharEquipBattleItem2			= 81,	//战斗物品2
		CharEquipBattleItem3			= 82,	//战斗物品3
		CharEquipBattleItem4			= 83,	//战斗物品4
		CharEquipBattleItem5			= 84,	//战斗物品5
		CharEquipBattleItem6			= 85,	//战斗物品6
		CharEquipBattleItem7			= 86,	//战斗物品7
		CharEquipBattleItem8			= 87,	//战斗物品8
		
		CharEquipLayerMax			= 90 
	};



public:
	Character(ResourceManager* creator, const String& name, ResourceHandle handle,
            const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
	~Character(void);

protected:
       	void prepareImpl(void);
        /** Destroys data cached by prepareImpl.
         */
        void unprepareImpl(void);
        /// @copydoc Resource::loadImpl
        bool loadImpl(void);
        /// @copydoc Resource::postLoadImpl
        void postLoadImpl(void);

	void preUnloadImpl(void);
        /// @copydoc Resource::unloadImpl
        void unloadImpl(void);
        /// @copydoc Resource::calculateSize
        size_t calculateSize(void) const;
	bool loadChildrenFromDB(void);
private:
	std::list<ResourceProxy>	m_chars;	// 武将副将列表
	std::list<ResourceProxy>	m_items;	// 武将装备的物品
	std::list<ResourceProxy>	m_effects;	//角色作用的效果
	std::list<ResourceProxy>	m_missions;	//角色作用的任务
	uint64		m_guid;
	uint32		m_serial;
	uint32		m_group_id;
	String 		m_name; 	// '物品名称',

	void	initialize(void);

	bool            m_idle;
        uint32          m_timelast;
public:
	
        const uint32  & getSerial()     {       return m_serial;        }
        const uint32  & getGroup_id()   {       return m_group_id;      }
        const uint64  & getGuid()       {       return m_guid;          }       
	const void  setGuid(const uint64 & set)	{	m_guid = set;	}

        const String & getCharName()            {       return m_name;          }

	bool hasChildren(void)  {       return true;    }

	//检查是否进行自动更新
        bool    checkUpdate(const uint32 & timenow)     {  return (m_idle && timenow > m_timelast) ? true:false;}
        void    updateTimeLast(const uint32 & timelast) {       m_timelast = timelast;  }
        //设置处理标识为忙，避免重复队列处理
        void    setBusy(void)           {       m_idle = false; }
        void    setIdle(void)           {       m_idle = true;  }
        bool    isBusy(void)            {       return (m_idle == false);       }

	//添加释放容器物品包含的物品
	bool	addItem(const uint32 & serial);
	bool  	addItem(ResourceProxy & item);
	bool	removeItem(const uint32 & serial);
	bool	removeItem(ResourceProxy & item);
	bool	deleteItem(const uint32 & serial);
	bool	deleteItem(ResourceProxy & item);
	bool	destroyItem(const uint32 & serial);
	bool	destroyItem(ResourceProxy & item);
	void	removeAllItems(void);
	void	destroyAllItems(void);
	void	deleteAllItems(void);

	//添加释放容器角色的副将
	bool	addChar(const uint32 & serial);
	bool  	addChar(ResourceProxy & ch);
	bool	removeChar(const uint32 & serial);
	bool	removeChar(ResourceProxy & ch);
	bool	deleteChar(const uint32 & serial);
	bool	deleteChar(ResourceProxy & ch);
	bool	destroyChar(const uint32 & serial);
	bool	destroyChar(ResourceProxy & ch);
	void	removeAllChars(void);
	void	destroyAllChars(void);
	void	deleteAllChars(void);

	//添加效果到角色
	bool	addEffect(const uint32 & serial);
	bool	addEffect(ResourceProxy & effect);
	bool	removeEffect(const uint32 & serial);
	bool	removeEffect(ResourceProxy & effect);
	bool	deleteEffect(const uint32 & serial);
	bool	deleteEffect(ResourceProxy & effect);
	bool	destroyEffect(const uint32 & serial);
	bool	destroyEffect(ResourceProxy & effect);
	void	removeAllEffects(void);
	void	destroyAllEffects(void); 
	void	deleteAllEffects(void); 
	
	//添加任务到角色
	bool	addMission(const uint32 & serial);
	bool	addMission(ResourceProxy & mission);
	bool	removeMission(const uint32 & serial);
	bool	removeMission(ResourceProxy & mission);
	bool	deleteMission(const uint32 & serial);
	bool	deleteMission(ResourceProxy & mission);
	bool	destroyMission(const uint32 & serial);
	bool	destroyMission(ResourceProxy & mission);
	void	removeAllMissions(void);
	void	destroyAllMissions(void); 
	void	deleteAllMissions(void); 
	
	//save character to database
	bool	SaveDB(void);
	bool	LoadDB(void);
	bool    FetchDB(Field * fields);


	size_t	loadItemsFromDB(void);
	size_t	loadEffectsFromDB(void);
	size_t	loadMissionsFromDB(void);
	size_t  loadCharsFromDB(void);

	//武将公共属性
	character_common_property_t 	common;
	
	//得到武将军队血量总数
	uint32		getArmiesHP(void);
	//得到武将有效军队个数
	uint16		getArmiesNum(void);

	//武将是否NPC
	bool		isNPC(void);

	//得到武将关联的Socket
	ResourcePtr	getSocket(void);


	//得到包含物品的列表复制
	std::list<ItemPtr> * getItemsList(std::list<ItemPtr> * list);

	//得到包括特效的列表复制
	std::list<EffectPtr> * getEffectsList(std::list<EffectPtr> * list);


	//得到包括任务的列表复制
	std::list<MissionPtr> * getMissionsList(std::list<MissionPtr> * list);
	
	//得到副将列表
	std::list<ResourcePtr> * getCharsList(std::list<ResourcePtr> * list);


	const CharacterStatus  &  getStatus(void)	{	return common.status;	}
	void setStatus(const CharacterStatus & status);
	

	//用户数据
        XMLDataSet      user_data;

	//得到武将君主Handle
	uint32	getOwnerHandle(void);
	//得到武将君主
	CharPtr	getOwner(void);

	//战斗相关


	void Delete(void);
	void Destroy(void);

	
};

    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to ItemPtr 
    @note Has to be a subclass since we need operator=.
    We could templatise this instead of repeating per Resource subclass, 
    except to do so requires a form VC6 does not support i.e.
    ResourceSubclassPtr<T> : public SharedPtr<T>
    */
    class SERVER_DECL  CharPtr : public SharedPtr<Character>
    {
    public:
        CharPtr() : SharedPtr<Character>() {}
        explicit CharPtr(Character * rep) : SharedPtr<Character>(rep) {}
        CharPtr(const CharPtr& r) : SharedPtr<Character>(r) {}
        CharPtr(const ResourcePtr& r);
        /// Operator used to convert a ResourcePtr to a MeshPtr
        CharPtr& operator=(const ResourcePtr& r);
    protected:
        /// Override destroy since we need to delete Mesh after fully defined
        void destroy(void);
    };
	


#endif
